package main

import (
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/go-playground/validator/v10"
)

//自定义验证器
func main() {
	r := gin.Default()

	//把验证器注册到Validator里面去
	if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
		v.RegisterValidation("bookabledate", bookableDate, true)
	}
	//

	r.GET("/myvalidator", func(c *gin.Context) {
		var b Booking
		if err := c.ShouldBind(&b); err != nil {
			c.JSON(500, gin.H{
				"error": err.Error(),
			})
			return
		}
		c.JSON(200, gin.H{
			"message": "OK!",
			"booking": b,
		})
	})
	//run
	r.Run(":8081")
	//演示结果：
	//http://localhost:8081/myvalidator?check_in=2021-04-22&check_out=2021-05-11
}

type Booking struct {
	CheckIn  time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`     //预约时间要大于当前时间，所以需要自定义一个验证器来验证
	CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn" time_format:"2006-01-02"` //该字段时间必须大于CheckIn的时间，所以用已有验证gtfield
}

//自定义验证器
//validator v9以上写法
func bookableDate(fl validator.FieldLevel) bool {
	if date, ok := fl.Field().Interface().(time.Time); ok { //fl.Field()获取到的字段值是reflect.Value类型，需要调用接口函数转换成接口
		today := time.Now()
		fmt.Println("date:", date)
		if date.Unix() > today.Unix() {
			fmt.Println("date unix ：", date.Unix())
			return true
		}
	}
	return false
}
